package com.yungu.swift.assets.driver.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.google.common.collect.Lists;
import com.yungu.swift.assets.driver.dao.DriverMapper;
import com.yungu.swift.assets.driver.model.dto.DriverDto;
import com.yungu.swift.assets.driver.model.dto.DriverStatusCycleDto;
import com.yungu.swift.assets.driver.model.dto.MonitorStatDto;
import com.yungu.swift.assets.driver.model.param.AdminDriverMonitorParam;
import com.yungu.swift.assets.driver.model.vo.AdminDriverMonitorVo;
import com.yungu.swift.assets.driver.model.vo.AdminMonitorDriverDetailVo;
import com.yungu.swift.assets.driver.model.vo.AdminMonitorDriverStatusVo;
import com.yungu.swift.assets.driver.model.vo.MonitorDriverListVo;
import com.yungu.swift.assets.driver.service.DriverMonitorService;
import com.yungu.swift.assets.driver.service.DriverStatusCycleService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.lbs.model.DriverLocation;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.utils.DateUtils;
import com.yungu.swift.utils.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author cuixiuyin
 * @Date 2018/12/22 11:15
 * @Version 1.0
 */
@Service
public class DriverMonitorServiceImpl implements DriverMonitorService {

    @Autowired
    private DriverMapper driverMapper;

    @Reference
    private LocationService locationService;
    @Reference
    private DriverStatusCycleService driverStatusCycleService;

    @Override
    public ResponseData<AdminDriverMonitorVo> getDriverList(AdminDriverMonitorParam monitorParam) {
        AdminDriverMonitorVo adminDriverMonitorVo = new AdminDriverMonitorVo();
        List<MonitorStatDto> statOnlineDriversTodayList = driverMapper.statOnlineDriversToday(monitorParam);
        //获取每个状态的总数
        for (MonitorStatDto monitorStatDto : statOnlineDriversTodayList) {
            if(monitorStatDto.getCurrentStatus()==null){
                continue;
            }
            switch (monitorStatDto.getCurrentStatus()) {
                case 1:
                    adminDriverMonitorVo.setEmptyCount(monitorStatDto.getCount());
                    break;
                case 2:
                    adminDriverMonitorVo.setPickupCount(monitorStatDto.getCount());
                    break;
                case 3:
                    adminDriverMonitorVo.setCarryCount(monitorStatDto.getCount());
                    break;
                case 4:
                    adminDriverMonitorVo.setOffworkCount(monitorStatDto.getCount());
                    break;
                case 5:
                    adminDriverMonitorVo.setOfflineCount(monitorStatDto.getCount());
                    break;
                default:
                    break;
            }
        }
        PageBounds pageBounds = new PageBounds(monitorParam.getPageNum(), monitorParam.getPageSize());
        PageList<MonitorDriverListVo> pageList = driverMapper.listTodayDriverMonitor(monitorParam, pageBounds);
        fullStatusLngLat(pageList, monitorParam.getAppid());
        // 今日司机分页数据
        PageVo<MonitorDriverListVo> pageVo = new PageVo(monitorParam.getPageNum(), monitorParam.getPageSize(),
                pageList.getPaginator().getTotalCount());
        pageVo.setItems(pageList);
        adminDriverMonitorVo.setPageVo(pageVo);
        return ResponseData.buildSuccessResponse(adminDriverMonitorVo);
    }

    @Override
    public ResponseData<AdminMonitorDriverDetailVo> getMonitorDriverDetail(String driverUuid) {
        Map<String, Object> build = MapUtils.build("driverUuid", driverUuid);
        List<DriverDto> dtoList = driverMapper.list(build);
        if (CollectionUtils.isNotEmpty(dtoList)) {
            DriverDto driverDto = dtoList.get(0);
            //跨城司机与非跨城显示不同信息
            if (!driverDto.getBusinessType().equals(CommonConstant.CAR_TYPE_POOL)) {
                List<AdminMonitorDriverDetailVo> result = driverMapper.getMonitorDriverDetail(build);
                if (CollectionUtils.isNotEmpty(result)) {
                    AdminMonitorDriverDetailVo driverDetailVo = result.get(0);
                    // 在线时长 = 出车时长 - 离线时长
                    driverDetailVo.setOnLineTime(driverDetailVo.getOnWorkTimeSum().subtract(driverDetailVo.getOffLineTime()));
                    // 单位换算 - 出车时长
                    driverDetailVo.setOnWorkTimeSum(driverDetailVo.getOnWorkTimeSum().divide(BigDecimal.valueOf(3600.0), 2, BigDecimal.ROUND_HALF_UP));
                    // 单位换算 - 离线时长
                    driverDetailVo.setOffLineTime(driverDetailVo.getOffLineTime().divide(BigDecimal.valueOf(3600.0), 2, BigDecimal.ROUND_HALF_UP));
                    // 单位换算 — 在线时长
                    driverDetailVo.setOnLineTime(driverDetailVo.getOnLineTime().divide(BigDecimal.valueOf(3600.0), 2, BigDecimal.ROUND_HALF_UP));
                    return ResponseData.buildSuccessResponse(driverDetailVo);
                }
            } else {
                AdminMonitorDriverDetailVo adminMonitorDriverDetailVo = driverMapper.getDriverTodayCrosstownInfo(build);
                if (adminMonitorDriverDetailVo != null) {
                    return ResponseData.buildSuccessResponse(adminMonitorDriverDetailVo);
                }
            }

        }
        return ResponseData.buildSuccessResponse(new AdminMonitorDriverDetailVo());
    }

    @Override
    public ResponseData<List<AdminMonitorDriverStatusVo>> getMonitorDriverStatus(String driverUuid, String appid) {
        List<AdminMonitorDriverStatusVo> list = Lists.newArrayList();

        Map<String, Object> build = MapUtils.build(4);
        build.put("appid", appid);
        build.put("driverUuid", driverUuid);
        build.put("recordDate", DateUtils.format(new Date(), "yyyy-MM-dd"));
        List<DriverStatusCycleDto> driverStatusCycleDtos = driverStatusCycleService.list(build).getData();
        if (CollectionUtils.isNotEmpty(driverStatusCycleDtos)) {
            List<DriverLocation> driverLocations = locationService.findDriverTodayMapPoint(driverUuid, appid).getData();
            if (driverLocations != null) {
                for (DriverStatusCycleDto driverStatusDto : driverStatusCycleDtos) {
                    AdminMonitorDriverStatusVo driverStatusVo = new AdminMonitorDriverStatusVo();
                    BeanUtils.copyProperties(driverStatusDto, driverStatusVo);
                    long startTime = driverStatusDto.getStartTime().getTime();
                    long endTime = driverStatusDto.getEndTime() == null ? System.currentTimeMillis() : driverStatusDto.getEndTime().getTime();
                    List<DriverLocation> collect = driverLocations.stream().parallel().filter(driverLocation -> {
                        return driverLocation.getUploadTime().getTime() >= startTime
                                && driverLocation.getUploadTime().getTime() <= endTime;
                    }).collect(Collectors.toList());
                    driverStatusVo.setPointsList(collect);
                }
            }
        }
        return ResponseData.buildSuccessResponse(list);
    }

    private void fullStatusLngLat(List<MonitorDriverListVo> monitorDriverListVos, String appid) {
        ResponseData<List<DriverLocation>> allNewsDriverPoint = locationService.getAllNewsDriverPoint(
                CommonConstant.BUSINESS_ALL, CommonConstant.CARTYPE_ALL, appid);
        if (!allNewsDriverPoint.isSuccess() || CollectionUtils.isEmpty(allNewsDriverPoint.getData())) {
            return;
        }
        //这边从mongodb取出定位点
        Map<String, DriverLocation> driverLocationMap = allNewsDriverPoint.getData().stream().parallel().collect(
                Collectors.toMap(DriverLocation::getDriverUuid, driverLocation -> driverLocation, (oldValue, newValue) -> newValue));
        for (MonitorDriverListVo monitorVo : monitorDriverListVos) {
            String driverUuid = monitorVo.getDriverUuid();
            if (driverLocationMap.get(driverUuid) != null) {
                DriverLocation location = driverLocationMap.get(driverUuid);
                Double driverLastLng = location.getCoordinate().getLng();
                Double driverLastLat = location.getCoordinate().getLat();
                setLngLat(monitorVo, driverLastLat, driverLastLng);
            } else {
                setLngLat(monitorVo, 0d, 0d);
            }
        }
    }

    /**
     * 设置司机状态和最后当前经纬度
     *
     * @param bean
     * @param status
     * @param driverLastLng
     * @param driverLastLat
     */
    private void setStatusLngLat(MonitorDriverListVo bean, String status, Double driverLastLng, Double driverLastLat) {
        bean.setCurrentStatus(status);
        bean.setCurrentLat(driverLastLat);
        bean.setCurrentLng(driverLastLng);
    }

    /**
     * 设置司机最后当前经纬度
     *
     * @param bean
     * @param driverLastLng
     * @param driverLastLat
     */
    private void setLngLat(MonitorDriverListVo bean, Double driverLastLat, Double driverLastLng) {
        bean.setCurrentLat(driverLastLat);
        bean.setCurrentLng(driverLastLng);
    }


}
